import React, { Component } from 'react';
import { Button, Message, Loading } from '@alifd/next';
import PropTypes from 'prop-types';
import COS from 'cos-js-sdk-v5';
import '@alifd/next/lib/upload/style';
import request from '../../utils/request';
import { DB_SETTING } from '../../utils/db';
import { remote } from '../../utils/electron';
import { MD5, getExtend, getHttpLink } from '../../utils/helper';


class CosUploader extends Component {
  static displayName = 'CosUploader';

  static defaultProps = {
    auto: true, // 是否选择了文件后自动上传图片
    onUpload: PropTypes.func,
    detailId: 0,
    detailTable: '',
    author: 0,
    files: [],
    max: 20,
  }

  constructor(props) {
    super(props);
    this.state = {
      showLoading: false,
      pictureList: [],
    };
  }
  componentWillReceiveProps(nextProps) {
    const files = nextProps.files || [];
    if (files.length > 0) {
      const { pictureList } = this.state;
      for (let i = 0; i < files.length; i += 1) {
        const fileItem = files[i];
        const link = fileItem.link || '';
        const id = fileItem.id || '';
        if (link && link.length && !pictureList.find(item => item.path === link)) {
          pictureList.push({
            status: '',
            done: true,
            new: false,
            key: `${MD5(`${link}${new Date().getTime()}`)}.${getExtend(link)}`,
            src: link,
            path: link,
            name: link,
            item: fileItem,
            id,
          });
        }
      }
      this.setState({
        pictureList,
      });
    }
  }

  openItem = (e) => {
    remote.shell.openItem(e);
  }

  removeItem = (reItem) => {
    const { pictureList } = this.state;
    const list = pictureList.filter(item => item.src !== reItem.src);
    this.setState({
      pictureList: list,
    });
    if (reItem.id && (reItem.id.length > 0 || reItem.id > 0)) {
      this.deleteFromServe(reItem.id);
    }
  }

  fileInputChange = async (e) => {
    const { max, auto } = this.props;
    const { pictureList } = this.state;
    const files = e.currentTarget.files;
    let length = Object.keys(files).length;
    if (max < pictureList.length + length) { // 如果选的数量超过了
      length = max - pictureList.length;
    }
    await Promise.all([...Array(length).keys()].map(async (item, index) => {
      await this.readAsDataURL(files[index]);
    }));
    if (auto) {
      await this.uploadAll();
    }
  }

  readAsDataURL = (file) => {
    const { pictureList } = this.state;
    return new Promise((resolve) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        if (!pictureList.find(pic => pic.path === file.path)) {
          pictureList.push({
            status: '(待上传)',
            done: true,
            new: true,
            key: `${MD5(file.path)}.${getExtend(file.path)}`,
            src: reader.result,
            path: file.path,
            name: file.name,
            item: file,
          });
          this.setState({
            pictureList,
          }, () => resolve());
        }
      };
    });
  }
  getFiles = () => {
    const { pictureList } = this.state;
    const list = pictureList.filter((item, index) => {
      return index < 9;
    }).map((item) => {
      return item.path;
    });
    return list.join(',');
  }

  uploadAll = async () => {
    const { onUpload } = this.props;
    const { pictureList } = this.state;
    // let cosSetting = localStorage.getItem('cos-js-v5-setting') || '';
    try {
      const queryOne = await DB_SETTING().where('key').equals('cos-js-v5-setting').first();
      let cosSetting = queryOne.value || '';
      if (cosSetting.length < 1) {
        return Message.error('腾讯云文件管理配置缺失');
      }
      cosSetting = JSON.parse(cosSetting);
      if (!cosSetting.SecretId || !cosSetting.SecretKey || !cosSetting.Bucket || !cosSetting.Region) {
        return Message.error('腾讯云文件管理配置缺失');
      }
      const COSObject = new COS({
        SecretId: cosSetting.SecretId,
        SecretKey: cosSetting.SecretKey,
      });
      this.setState({
        showLoading: true,
      });
      await Promise.all(pictureList.map(async (item, index) => {
        if (item.new) {
          await this.uploadAction(COSObject, cosSetting, item, index);
        }
      }));
      const list = this.state.pictureList.map((item) => {
        return item.path;
      });
      this.setState({
        showLoading: false,
      });
      onUpload(list.join(','));
    } catch (e) {
      Message.error(e.toString());
    }
  }
  uploadAction = (COSObject, cosSetting, item, index) => {
    const { pictureList } = this.state;
    pictureList[index].status = '(上传中...)';
    this.setState({
      pictureList,
    });
    return new Promise((resolve, reject) => {
      COSObject.sliceUploadFile({
        Bucket: cosSetting.Bucket,
        Region: cosSetting.Region,
        Key: item.key,
        Body: item.item,
      }, (err, data) => {
        if (err && err.error) {
          Message.error(err.error);
          this.setState({
            showLoading: false,
          });
          reject(err);
        }
        if (data && data.Location && data.Location.length) {
          const dataLocation = getHttpLink(data.Location);
          pictureList[index].status = '';
          pictureList[index].path = dataLocation;
          pictureList[index].new = false;
          // 这里上传了图片，在后台保存一下
          this.putToServe(item.name, dataLocation, index).then((res) => {
            pictureList[index].id = res.data.id;
            this.setState({
              pictureList,
            }, () => {
              resolve(dataLocation);
            });
          });
        } else {
          resolve();
        }
      });
    });
  }
  // 图片上传了，保存到服务器表里
  putToServe = (title, link, sort) => {
    const { author, detailId, detailTable } = this.props;
    return request.put('/pictureItem', {
      author,
      detailId,
      detailTable,
      link,
      sort,
      title,
    });
  }
  deleteFromServe = (id) => {
    request.delete(`/pictureItem/${id}`);
  }
  render() {
    const { max, auto } = this.props;
    const { pictureList, showLoading } = this.state;
    return (
      <Loading visible={showLoading} fullScreen tip="图片上传中...">
        {
          !auto && (<div style={{ padding: '10px 0' }}><Button type="primary" size="small" onClick={this.uploadAll}>上传图片</Button></div>)
        }
        <div className="next-upload-list next-upload-list-card">
          {
            pictureList.map((item) => {
              return item.done && (
                <div className="next-upload-list-item next-upload-list-item-done" key={item.key}>
                  <div className="next-upload-list-item-wrapper">
                    <div className="next-upload-list-item-thumbnail">
                      <img src={item.src} alt={item.name} />
                    </div>
                    <span className="next-upload-tool ">
                      <span onClick={this.openItem.bind(this, item.path)}>
                        <i className="next-icon next-icon-download next-medium next-upload-tool-download-icon" />
                      </span>
                      <span className="next-upload-tool-close" onClick={this.removeItem.bind(this, item)}>
                        <i className="next-icon next-icon-ashbin next-medium" />
                      </span>
                    </span>
                  </div>
                  <span className="next-upload-list-item-name" title={item.name}>({item.id}){item.status}{item.name}</span>
                </div>
              );
            })
          }
          <div className="next-upload-inner" style={style.fileInputParent}>
            {
              max > pictureList.length && (
                <input type="file" multiple={max > 1} onChange={this.fileInputChange} name="file" accept="image/png, image/jpg, image/jpeg, image/gif, image/bmp" aria-hidden="true" style={style.fileInput} />
              )
            }
            <div className="next-upload-card">
              <i className="next-icon next-icon-add next-large" />
              <div tabIndex="0" role="button" className="next-upload-text">({`${pictureList.length}/${max}`})选择图片</div>
            </div>
          </div>
        </div>
      </Loading>
    );
  }
}

export default CosUploader;

const style = {
  fileInput: {
    position: 'absolute',
    top: '0',
    left: '0',
    width: '100%',
    height: '100%',
    opacity: '0',
  },
  fileInputParent: {
    position: 'relative',
  },
}
